﻿using System;
using System.Web.UI;
using Microsoft.SharePoint;
using System.IO;
using System.Web.UI.WebControls;
using Evolution.Utilities;
using Evolution.Expression;

namespace Evolution.UI.WebParts
{
    [Serializable]
    public class RedirectToAction : BaseAction
    {
        #region Constructors

        public RedirectToAction()
        {

        }

        public RedirectToAction(string url, RedirectMode mode)
        {
            this.Url = url;
            this.Mode = mode;
        }

        #endregion

        #region Properties

        public string Url { get; set; }

        public RedirectMode Mode { get; set; }

        public override string Caption
        {
            get { return "Redirect to"; }
        }

        public override bool RequireCondition
        {
            get { return true; }
            set { }
        }

        #endregion

        #region Methods

        public override void CreateInterface(ControlCollectionBuilder builder, PageActionEditor editor)
        {
            builder.AddStaticText(@"<div class=""UserControlBody"" style=""margin-top: 5px"">Type a Url.</div>");
            builder.AddStaticText(@"<div class=""UserControlGroup"" style=""padding-bottom: 2px"">");

            TextBox url = new TextBox();
            url.ID = "Evolution_Pawp_Url";
            url.CssClass = "UserInput";
            url.ToolTip = "Url Link";
            url.Style[HtmlTextWriterStyle.Width] = "175px";

            builder.AddTextBoxAndBuilder(url, true);

            builder.AddStaticText("</div>");

            builder.AddErrorPlaceholder("Url");

            builder.AddStaticText(@"<div class=""UserControlBody"" style=""margin-top: 5px"">Specify the redirection mode.</div>");
            builder.AddStaticText(@"<div class=""UserControlGroup"" style=""padding-bottom: 2px"">");

            RadioButtonList redirectOpts = new RadioButtonList();
            redirectOpts.ID = "Evolution_Pawp_RedirectOptions";
            redirectOpts.CssClass = "UserInput";

            ListItem direct = new ListItem("Direct");
            direct.Selected = true;
            redirectOpts.Items.Add(direct);
            redirectOpts.Items.Add(new ListItem("Relative to layouts"));
            redirectOpts.Items.Add(new ListItem("Use Source"));

            builder.AddControl(redirectOpts);

            builder.AddStaticText("</div>");
        }

        public override void Execute(Page page, PageActionWebPart part)
        {
            ExpressionInterpreter interp = PageActionWebPart.GetInterpreter(page, part);
            string url = "";
            switch (this.Mode)
            {
                case RedirectMode.Direct:
                    url = interp.ParseExpression(this.Url);
                    page.Response.Redirect(url, false);
                    break;
                case RedirectMode.RelativeToLayouts:
                    url = interp.ParseExpression(this.Url);
                    page.Response.Redirect(Path.Combine(Path.Combine(SPContext.Current.Site.Url, "_layouts"), url), false);
                    break;
                case RedirectMode.UseSource:
                    url = page.Request.QueryString["Source"];
                    if (StringUtility.IsNullOrEmpty(url))
                    {
                        url = page.Request.QueryString["NextUsing"];
                        if (StringUtility.IsNullOrEmpty(url))
                        {
                            url = page.Request.QueryString["NextPage"];
                            if (StringUtility.IsNullOrEmpty(url))
                            {
                                url = interp.ParseExpression(this.Url);
                                if (StringUtility.IsNullOrEmpty(url))
                                    url = SPContext.Current.Web.Url;
                            }
                        }
                    }
                    page.Response.Redirect(url, false);
                    break;
                default:
                    throw new ArgumentOutOfRangeException("The redirection mode can not be RedirectMode.None.");
            }
        }

        public override bool IsValidAction(PageActionWebPart part, out string errorMessage)
        {
            errorMessage = String.Empty;
            if (StringUtility.IsNullOrEmpty(this.Url) && this.Mode != RedirectMode.UseSource)
                errorMessage = "No new URL specified";

            if(this.Mode== RedirectMode.None)
                errorMessage = (String.IsNullOrEmpty(errorMessage) ? "" : errorMessage + "<br/>") + "No redirect method specified";

            return String.IsNullOrEmpty(errorMessage);
        }

        public override string GetDescription()
        {
            return "Redirect to";
        }

        public override void ApplyChanges(PageActionEditor editor)
        {
            TextBox text1 = editor.FindControl("Evolution_Pawp_Url") as TextBox;
            RadioButtonList list = editor.FindControl("Evolution_Pawp_RedirectOptions") as RadioButtonList;

            RedirectMode mode = (RedirectMode)(list.SelectedIndex + 1);

            if (text1.Text.Trim() == String.Empty && mode != RedirectMode.UseSource)
                editor.RaiseError("Url", "<br/>Specify a target location.", String.Format("The action '{0}' requires the indication of a new URL.", this.Caption));

            this.Url = text1.Text;
            this.Mode = mode;
        }

        public override void SyncChanges(PageActionEditor editor)
        {
            (editor.FindControl("Evolution_Pawp_Url") as TextBox).Text = this.Url;

            RadioButtonList redirectOpts = editor.FindControl("Evolution_Pawp_RedirectOptions") as RadioButtonList;
            RedirectMode mode = this.Mode;

            if (mode == RedirectMode.None)
                mode = RedirectMode.Direct;

            redirectOpts.SelectedIndex = ((int)mode) - 1;            
        }

        #endregion
    }

    #region RedirectMode enum

    public enum RedirectMode
    {
        None = 0,
        Direct = 1,             // Navigate to the address (absolute or relative)
        RelativeToLayouts = 2,
        UseSource = 3           // Takes the address from the query string keys "Source", "NextUsing" or "NextPage". 
                                // If no key is present, skips to the welcome page of the site.
    }

    #endregion
}
